Source for file SC_Pdf.php

Documentation is available at SC_Pdf.php

  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) 2000-2007 LOCKON CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.lockon.co.jp/
  8.  *
  9.  * This program is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License
  11.  * as published by the Free Software Foundation; either version 2
  12.  * of the License, or (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22.  */
  23.  
  24. /*----------------------------------------------------------------------
  25.  * [名称] GC_Pdf
  26.  * [概要] Pdfファイルを表示する。(PDFLib必須)
  27.  *----------------------------------------------------------------------
  28.  */
  29.  
  30. // グリッドと文字の間隔 
  31. define("GRID_SPACE", 4);
  32.  
  33. class SC_Pdf {
  34.     var $arrText;
  35.     var $arrImage;
  36.     var $license_key;
  37.     var $block_option;
  38.     var $src_code;
  39.     var $dst_code;
  40.     var $pdiwarning;
  41.     var $pdfpath;
  42.     var $page_close;
  43.             
  44.     function SC_Pdf($width = 595, $height = 842, $fontsize = 10) {
  45.         $this->license_key = "B600602-010400-714251-5851C1";
  46.         $this->src_code = CHAR_CODE;
  47.         // UTF-8でないとブロック内で改行できない。
  48.         $this->dst_code = "UTF-8";
  49.         // PDF BLOCKのプロパティ
  50.         $this->block_option = "encoding=UniJIS-UCS2-H textformat=utf8 fontname=HeiseiMin-W3 textflow=true";
  51.         // 警告表示
  52.         $this->pdiwarning = "true";    
  53.         // ページサイズ設定
  54.         $this->width = $width;
  55.         $this->height = $height;
  56.         // PDF初期化
  57.         $this->pdf = PDF_new();
  58.         PDF_set_parameter($this->pdf, "license", $this->license_key);
  59.         PDF_set_parameter($this->pdf, "pdiwarning", $this->pdiwarning);
  60.         // ドキュメント開始
  61.         PDF_begin_document($this->pdf, NULL, NULL);
  62.         // ページの状態
  63.         $this->page_open = false;
  64.         // テーブルの色設定
  65.         $this->setTableColor();
  66.         // フォントサイズの設定
  67.         $this->fontsize = $fontsize;
  68.         // グリッド描画の特殊指定
  69.         $this->arrLines = array();
  70.         // テーブルタイトルのスタイル
  71.         $this->arrHeaderColSize = array();
  72.         $this->arrHeaderAlign = array();
  73.         // テーブル補正値
  74.         $this->table_left = 0;
  75.         // タイトル行の出力
  76.         $this->title_enable = true;
  77.         // グリッドの出力
  78.         $this->grid_enable = true;
  79.     }
  80.     
  81.     // タイトルを出力するか否か
  82.     function setTitleEnable($flag) {
  83.         $this->title_enable = $flag;
  84.     }
  85.     
  86.     // グリッドを出力するか否か
  87.     function setGridEnable($flag) {
  88.         $this->grid_enable = $flag;
  89.     }
  90.         
  91.         
  92.     // キー:ブロック名、値:表示テキストのハッシュ配列をセットする。
  93.     function setTextBlock($list) {
  94.         unset($this->arrText);
  95.         $this->arrText[] = $list;
  96.     }
  97.     
  98.     // キー:ブロック名、値:ファイルパスのハッシュ配列をセットする。
  99.     // ※パスはドキュメントルート以下
  100.     function setImageBlock($list) {
  101.         unset($this->arrImage);
  102.         $this->arrImage[] = $list;
  103.     }
  104.     
  105.     // 表示背景となるテンプレートファイルパス
  106.     // ※パスはドキュメントルート以下
  107.     function setTemplate($pdfpath) {
  108.         if(file_exists($pdfpath)) {
  109.             $this->pdfpath = $pdfpath;
  110.         } else {
  111.             print("指定したPDFテンプレートは存在しません:".$pdfpath);
  112.             exit;
  113.         }
  114.     }
  115.     
  116.     // テーブル位置補正値
  117.     function setTableLeft($table_left) {
  118.         $this->table_left = $table_left;
  119.     }
  120.     
  121.     // グリッド描画の特殊指定
  122.     function setGridLines($list) {
  123.         $this->arrLines = $list;
  124.     }
  125.     
  126.     // テーブルタイトルのスタイル設定
  127.     function setTableHeaderStyle($arrColSize, $arrAlign) {
  128.         $this->arrHeaderColSize = $arrColSize;
  129.         $this->arrHeaderAlign = $arrAlign;
  130.     }
  131.     
  132.     // ブロックデータの書き込み(closeすると次回新規ページ)
  133.     function writeBlock() {
  134.         // テンプレートを使用する
  135.         if(!file_exists($this->pdfpath)) {
  136.             return;
  137.         }
  138.         // 既存PDFのドキュメントを取得
  139.         $doc = pdf_open_pdi($this->pdf, $this->pdfpath, NULL, 0 );
  140.         // 既存PDFのドキュメントから指定ページを取得
  141.         $page = pdf_open_pdi_page($this->pdf, $doc, 1, NULL );
  142.         // ページを開く
  143.         $this->openPage();
  144.         
  145.         // 既存PDFのページを割り当てる
  146.         PDF_fit_pdi_page($this->pdf, $page, 0, 0, "adjustpage");
  147.         
  148.         // テキストブロックの書き込み
  149.         $max = count($this->arrText);
  150.         for($i = 0;$i < $max; $i++) {
  151.             foreach($this->arrText[$i] as $key => $val) {
  152.                 if($val != "") {
  153.                     // 文字コードの変換
  154.                     mb_convert_variables($this->dst_code, $this->src_code, $val);
  155.                     // 書き込み
  156.                     $ret = PDF_fill_textblock($this->pdf, $page, $key, $val, $this->block_option);
  157.                 }
  158.             }
  159.         }
  160.         
  161.         // イメージブロックの書き込み
  162.         $max = count($this->arrImage);
  163.         for($i = 0;$i < $max; $i++) {
  164.             foreach($this->arrImage[$i] as $key => $val) {
  165.                 if($val != "") {
  166.                     $img = PDF_load_image($this->pdf, "auto", $val, NULL );
  167.                     $ret = PDF_fill_imageblock($this->pdf, $page, $key, $img, NULL);
  168.                 }
  169.             }
  170.         }
  171.         
  172.         // 割り当てたページを閉じる
  173.         PDF_close_pdi_page($this->pdf, $page);
  174.         // 割り当てたドキュメントを閉じる
  175.         PDF_close_pdi($this->pdf, $doc);
  176.     }
  177.     
  178.     // ページを閉じる
  179.     function closePage() {
  180.         if($this->page_open) {
  181.             // ページを閉じる
  182.             PDF_end_page_ext($this->pdf, NULL);
  183.             $this->page_open = false;
  184.         }        
  185.     }
  186.     
  187.     // ページを開く
  188.     function openPage() {
  189.         if(!$this->page_open) {
  190.             // 新しいページを開く    
  191.             PDF_begin_page_ext($this->pdf, $this->width, $this->height, NULL);
  192.             $this->page_open = true;
  193.         }
  194.     }
  195.     
  196.     // 新しいページを開く
  197.     function newPage() {
  198.         PDF_end_page_ext($this->pdf, NULL);
  199.         PDF_begin_page_ext($this->pdf, $this->width, $this->height, NULL);
  200.     }
  201.     
  202.     // アクティブなページのサイズを取得する
  203.     function getSize() {
  204.         $this->openPage();
  205.         $x = PDF_get_value($this->pdf, 'pagewidth', 0);
  206.         $y = PDF_get_value($this->pdf, 'pageheight', 0);
  207.         return array($x, $y);
  208.     }
  209.     
  210.     // 座標を入れ替えて取得する(左下(0,0)を左上(0,0)に変換)
  211.     function posTopDown($x, $y) {
  212.         $width = 0;
  213.         $height = 0;
  214.         list($width, $height) = $this->getSize();
  215.         // x座標は、変更の必要なし
  216.         $pdf_x = $x;
  217.         $pdf_y = $height - $y;
  218.         return array($pdf_x, $pdf_y);
  219.     }
  220.     
  221.     // テーブルカラーの設定
  222.     function setTableColor($frame_color = "000000", $title_color = "F0F0F0", $line_color = "D1DEFE", $last_color = "FDCBFE") {
  223.         $this->frame_color = $frame_color;
  224.         $this->title_color = $title_color;
  225.         $this->line_color = $line_color;
  226.         $this->last_color = $last_color;
  227.     }
  228.     
  229.     // テーブルのグリッドを表示する。
  230.     function writeGrid($x, $y, $arrCol, $line_max, $last_color_flg = true) {
  231.         // テーブル幅
  232.         $max = count($arrCol);
  233.         $width = 0;
  234.         for($i = 0; $i < $max; $i++) {
  235.             $width += $arrCol[$i];
  236.         }
  237.         
  238.         if($this->title_enable) { 
  239.             // タイトルグリッド描画
  240.             $this->writeFrameRect($x, $y + GRID_SPACE, $width + GRID_SPACE, $this->fontsize + GRID_SPACE, $this->title_color, $this->frame_color);
  241.         }
  242.         
  243.         // グリッド特殊指定あり
  244.         if(count($this->arrLines) > 0) {
  245.             $count = count($this->arrLines);
  246.             $pos = 0;
  247.             for($i = 0; $i < $count; $i++) {
  248.                 if(($i % 2) != 0) {
  249.                     // 行の間隔
  250.                     $down = ($pos + 1) * $this->fontsize * 1.5;
  251.                     // 描画する縦幅を求める
  252.                     $height = ($this->fontsize + GRID_SPACE) * $this->arrLines[$i] + ($this->arrLines[$i] - 1);
  253.                     // 行グリッド描画
  254.                     $this->writeRect($x, $y + GRID_SPACE + $down, $width + GRID_SPACE, $height, $this->line_color);
  255.                 }
  256.                 $pos += $this->arrLines[$i];    
  257.             }                        
  258.         } else {
  259.             for($i = 1; $i <= $line_max; $i++) {
  260.                 if(($i % 2) == 0) {
  261.                     // 行の間隔
  262.                     $down = $i * $this->fontsize * 1.5;
  263.                     // 行グリッド描画
  264.                     $this->writeRect($x, $y + GRID_SPACE + $down, $width + GRID_SPACE, $this->fontsize + GRID_SPACE, $this->line_color);
  265.                 }
  266.             }
  267.             // 最終行に色をつける場合
  268.             if($last_color_flg) {
  269.                 // 行の間隔
  270.                 $down = $line_max * $this->fontsize * 1.5;
  271.                 // 行グリッド描画
  272.                 $this->writeRect($x, $y + GRID_SPACE + $down, $width + GRID_SPACE, $this->fontsize + GRID_SPACE, $this->last_color);
  273.             }
  274.         }
  275.     }
  276.     
  277.     // グリッド用のアンダーラインを引く
  278.     /*
  279.         $x            :テーブル開始位置X軸
  280.         $y            :テーブル開始位置Y軸
  281.         $arrCol        :カラムサイズの配列
  282.         $line        :アンダーラインを引く行
  283.         $start_col    :アンダーライン開始カラム(0:開始カラム)
  284.      */
  285.     function writeUnderLine($x, $y, $arrCol, $line, $start_col = 0) {
  286.         // テーブル幅
  287.         $max = count($arrCol);
  288.         $width = 0;
  289.         for($i = 0; $i < $max; $i++) {
  290.             $width += $arrCol[$i];
  291.         }
  292.         
  293.         $start_x = 0;
  294.         for($i = 0; $i < $start_col; $i++) {
  295.             $start_x += $arrCol[$i];
  296.         }
  297.         
  298.         // アンダーラインのY座標を求める
  299.         $down = ($line + 1) * $this->fontsize * 1.5;
  300.         // 行グリッド描画
  301.         $sx = $x + $start_x + GRID_SPACE + $this->table_left;
  302.         $sy = $y + GRID_SPACE + $down - 1;
  303.         $ex = $x + $width + GRID_SPACE;
  304.         $ey = $sy;
  305.                 
  306.         $this->writeLine($sx, $sy, $ex, $ey);        
  307.     }
  308.     
  309.     // 真ん中横位置を求める
  310.     function getXCenter($width) {
  311.         $page_width = 0;
  312.         $page_height = 0;
  313.         list($page_width, $page_height) = $this->getSize();
  314.         $x = ($page_width - $width) / 2;
  315.         return $x;
  316.     }
  317.     
  318.     // 自動中央よせ
  319.     function writeTableCenter($table, $y, $arrCol, $arrAlign, $line_max = 256, $start_no = 1, $last_color_flg = false) {
  320.         // テーブルサイズ取得
  321.         $width = 0;
  322.         foreach($arrCol as $val) {
  323.             $width += $val;
  324.         }
  325.         // 中央よせ位置取得
  326.         $x = $this->getXCenter($width) + $this->table_left;
  327.         list($ret_x, $ret_y) = $this->writeTable($table, $x, $y, $arrCol, $arrAlign, $line_max, $start_no, $last_color_flg);
  328.         // X軸の座標を返す
  329.         return array($ret_x, $ret_y);
  330.     }
  331.     
  332.     // データの書き込み(closeすると次回新規ページ)
  333.     // $start_no:1行目(タイトル)を0とする。
  334.     // $line_max:タイトルを含まない行数
  335.     function writeTable($table, $x, $y, $arrCol, $arrAlign, $line_max = 256, $start_no = 1, $last_color_flg = false) {
  336.         $this->openPage();
  337.         
  338.         $table = ereg_replace("\n$", "", $table);
  339.                 
  340.         $arrRet = split("\n", $table);
  341.                                 
  342.         if($line_max > (count($arrRet) - $start_no)) {
  343.             $line_max = count($arrRet) - $start_no;
  344.         }
  345.         
  346.         // タイトル有効
  347.         if($this->grid_enable) {
  348.             // グリッドの描画
  349.             $this->writeGrid($x, $y, $arrCol, $line_max, $last_color_flg);
  350.         }
  351.         
  352.         // UnicodeエンコーディングとしてUTF-8を設定
  353.         PDF_set_parameter($this->pdf, "textformat", "utf8");
  354.         
  355.         // タイトル有効
  356.         if($this->title_enable) {
  357.             if(count($this->arrHeaderColSize) > 0 && count($this->arrHeaderAlign) > 0 ) {
  358.                 list($linecol, $aligncol, $width) = $this->getTableOption($this->arrHeaderColSize, $this->arrHeaderAlign);
  359.             } else {
  360.                 list($linecol, $aligncol, $width) = $this->getTableOption($arrCol, $arrAlign);
  361.             }    
  362.                         
  363.             // タイトル行の書き込み
  364.             $option = "ruler {" . $linecol . "} ";
  365.             $option.= "tabalignment {" . $aligncol . "} ";
  366.             $fontsize =  $this->fontsize;
  367.             $option.= "hortabmethod ruler leading=150% fontname=HeiseiKakuGo-W5 fontsize=$fontsize encoding=UniJIS-UCS2-H";
  368.             
  369.             $this->writeTableData($table, $x, $y, $width, 0, 0, $option);
  370.         }
  371.         
  372.         list($linecol, $aligncol, $width) = $this->getTableOption($arrCol, $arrAlign);
  373.         
  374.         // データ行の書き込み
  375.         $option = "ruler {" . $linecol . "} ";
  376.         $option.= "tabalignment {" . $aligncol . "} ";
  377.         $option.= "hortabmethod ruler leading=150% fontname=HeiseiMin-W3 fontsize=$this->fontsize encoding=UniJIS-UCS2-H";
  378.         
  379.         if($start_no <= 0) {
  380.             $start_no = 1;
  381.             $end_no = $line_max;
  382.         } else {
  383.             $end_no = $start_no + $line_max - 1;
  384.         }
  385.         
  386.         $y += $this->fontsize * 1.5;
  387.         
  388.         list($ret_x, $ret_y) = $this->writeTableData($table, $x, $y, $width, $start_no, $end_no, $option);
  389.         
  390.         return array($ret_x, $ret_y);
  391.     }
  392.     
  393.     function getTableOption($arrCol, $arrAlign) {
  394.         // カラムサイズ
  395.         $max = count($arrCol);
  396.         $width = 0;
  397.         for($i = 0; $i < $max; $i++) {
  398.             $width += $arrCol[$i];
  399.             $linecol.= $width . " ";
  400.         }
  401.         
  402.         // カラム位置
  403.         $max = count($arrAlign);
  404.         for($i = 0; $i < $max; $i++) {
  405.             $aligncol.= $arrAlign[$i] . " ";
  406.         }
  407.         
  408.         return array($linecol, $aligncol, $width);
  409.     }
  410.     
  411.     // テーブルデータの書き込み
  412.     function writeTableData($table, $x, $y, $table_width, $start_no, $end_no, $option) {
  413.         $arrLine = split("\n", $table);
  414.         for($i = $start_no; $i <= $end_no; $i++) {
  415.             $line.=$arrLine[$i] . "\n";
  416.         }
  417.                 
  418.         // テーブル位置を求める
  419.         list($pdf_x, $pdf_y) = $this->posTopDown($x, $y);
  420.                         
  421.         // テーブル高さを求める
  422.         $table_height = $this->fontsize * 1.5 * ($end_no - $start_no + 1);
  423.         // テーブル右下のy座標を求める
  424.         $end_y = $pdf_y - $table_height;
  425.         if($end_y < 0) {
  426.             $end_y = 0;
  427.         }
  428.         $enc_table = mb_convert_encoding($line, "utf-8", CHAR_CODE);
  429.                 
  430.         $tf = PDF_create_textflow($this->pdf, $enc_table, $option);
  431.  
  432.         PDF_fit_textflow($this->pdf, $tf, $pdf_x, $pdf_y, $pdf_x + $table_width, $end_y, NULL);
  433.         PDF_delete_textflow($this->pdf, $tf);
  434.         
  435.         // テーブル左下座標を返す
  436.         return array($x, $y + $table_height);        
  437.     }
  438.         
  439.     // 色の設定
  440.     function setColor($rgb) {
  441.         if($rgb != "") {
  442.             list($r, $g, $b) = sfGetPdfRgb($rgb);
  443.             PDF_setcolor($this->pdf, "fillstroke", "rgb", $r, $g, $b, 0);    
  444.         }
  445.     }
  446.     
  447.     // 短形を描画
  448.     function writeRect($x, $y, $width, $height, $rgb = "") {
  449.         $this->openPage();
  450.         list($pdf_x, $pdf_y) = $this->posTopDown($x, $y);
  451.         $this->setColor($rgb);
  452.         PDF_rect($this->pdf, $pdf_x,$pdf_y,$width,-$height);
  453.         PDF_fill($this->pdf);
  454.     }
  455.     
  456.     // 枠付の短形を描画
  457.     function writeFrameRect($x, $y, $width, $height, $rgb, $frgb) {
  458.         $this->openPage();
  459.         list($pdf_x, $pdf_y) = $this->posTopDown($x, $y);
  460.         $this->setColor($frgb);
  461.         PDF_rect($this->pdf, $pdf_x,$pdf_y,$width,-$height);
  462.         PDF_fill($this->pdf);
  463.         
  464.         $this->setColor($rgb);
  465.         PDF_rect($this->pdf, $pdf_x+1,$pdf_y-1,$width-2,-$height+2);
  466.         PDF_fill($this->pdf);        
  467.     }
  468.     
  469.     // 直線を描画
  470.     function writeLine($sx, $sy, $ex, $ey, $rgb = "000000") {
  471.         $this->openPage();
  472.         list($pdf_sx, $pdf_sy) = $this->posTopDown($sx, $sy);
  473.         list($pdf_ex, $pdf_ey) = $this->posTopDown($ex, $ey);
  474.         $this->setColor($rgb);
  475.         PDF_setlinewidth($this->pdf, 1.0);
  476.         PDF_moveto($this->pdf, $pdf_sx, $pdf_sy);
  477.         PDF_lineto($this->pdf, $pdf_ex, $pdf_ey);
  478.         PDF_stroke($this->pdf);
  479.     }
  480.         
  481.     // ファイルのダウンロード
  482.     function output($filekey = "") {
  483.         if(isset($this->pdf)) {
  484.             // ページを閉じる
  485.             $this->closePage();
  486.             // PDFの終了
  487.             PDF_end_document($this->pdf, NULL);
  488.             // 出力用データの取得 
  489.             $buf = PDF_get_buffer($this->pdf);
  490.             $filename = $filekey . date("ymdHis").".pdf";
  491.                         
  492.             header("Content-disposition: attachment; filename=$filename");
  493.             header("Content-type: application/octet-stream; name=$filename");
  494.                     
  495.             /*
  496.              * session_start()を事前に呼び出している場合に出力される以下のヘッダは、
  497.              * URL直接呼び出し時にエラーを発生させるので空にしておく。
  498.              *
  499.              * Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  500.              * Progma: no-cache
  501.              *
  502.              */
  503.             header("Cache-Control: ");
  504.             header("Pragma: ");
  505.             print $buf;
  506.             
  507.             // PDF解放
  508.             PDF_delete($this->pdf);
  509.         } else {
  510.             print("PDFが生成されていません。");
  511.         }
  512.         exit;        
  513.     }
  514.     
  515.     // ファイルの表示
  516.     function display() {
  517.         if(isset($this->pdf)) {
  518.             // ページを閉じる
  519.             $this->closePage();
  520.             // PDFの終了
  521.             PDF_end_document($this->pdf, NULL);
  522.             
  523.             // 出力用データの取得 
  524.             $buf = PDF_get_buffer($this->pdf);
  525.             $len = strlen($buf);
  526.             header("Content-type: application/pdf");
  527.             header("Content-Length: $len");
  528.             header("Content-Disposition: inline; filename=". date("YmdHis").".pdf");
  529.                                 
  530.             /*
  531.              * session_start()を事前に呼び出している場合に出力される以下のヘッダは、
  532.              * URL直接呼び出し時にエラーを発生させるので空にしておく。
  533.              *
  534.              * Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  535.              * Progma: no-cache
  536.              *
  537.              */
  538.             header("Cache-Control: ");
  539.             header("Pragma: ");
  540.             print $buf;
  541.             
  542.             // PDF解放
  543.             PDF_delete($this->pdf);
  544.         } else {
  545.             print("PDFが生成されていません。");
  546.         }
  547.         exit;
  548.     }
  549. }
  550.  
  551. ?>

Documentation generated on Tue, 28 Apr 2009 18:13:38 +0900 by phpDocumentor 1.4.2